package login

import (
	"data/config"
	"data/view/oauth2"
	"data/view/oplog"
	"data/view/user"
	"log"
	"strconv"
	"time"

	"data/view"
	"public/message"
	"public/mycache"
	"public/myhttp"
	"public/mysqldb"
	"public/tools"

	"encoding/json"

	"github.com/ant0ine/go-json-rest/rest"
)

//
var M_login Login

//
type Login struct {
}

/*
	登录
*/
func (a *Login) OnLogin(w rest.ResponseWriter, r *rest.Request) {
	//TODO 学生的话（已删除）不能登录
	var req map[string]string
	tools.GetRequestJsonObj(r, &req)

	username := req["username"]
	password := req["password"]
	times := req["time"]

	if len(username) == 0 || len(password) == 0 || len(times) == 0 {
		w.WriteJson(message.GetErrorMsg(message.ParameterInvalid))
		return
	}
	//判断是否手机号登录
	if len(username) <= 11 {
		if tools.IsPhone(username) {
			tmp := user.OnGetUserNameFromPhone(username)
			if len(tmp) > 0 { //手机号登录直接替换
				username = tmp
			}
		}
	}
	//-------------------------end
	mp := make(map[string]interface{})

	tmp := GetAccessTokenByUser(username, password, times)
	if tmp.State {
		mp["user"], _ = user.GetUserDetail(username)
		mp["token"] = tmp.Data
		msg := message.GetSuccessMsg(message.NormalMessageId)
		msg.Data = mp
		w.WriteJson(msg)
		var logs oplog.Op_log_tbl
		logs.Operator = username
		logs.Topic = "帐号系统"
		logs.Bundle = "登录"
		logs.Pid = "pc登录"
		logs.Ip_addr = tools.GetClientIp(r.Request)
		oplog.OpLogBaseAdd(logs) //保存日志
	} else {
		w.WriteJson(tmp)
	}
	return
}

/*
	验证token
*/
func (a *Login) CheckToken(w rest.ResponseWriter, r *rest.Request) {
	var req map[string]string
	tools.GetRequestJsonObj(r, &req)

	token := req["token"]
	username, _, b := user.GetUserFromToken(token)
	log.Println(username, b)
	if !b {
		w.WriteJson(message.GetErrorMsg(message.TokenFailure))
	} else {
		msg := message.GetSuccessMsg(message.NormalMessageId)
		parm := make(map[string]string)
		parm["username"] = username
		msg.Data = parm
		w.WriteJson(msg)
	}
}

/*
	刷新token管理员
*/
func (a *Login) RefreshToken(w rest.ResponseWriter, r *rest.Request) {
	var req map[string]string
	tools.GetRequestJsonObj(r, &req)
	token := req["refresh_token"]
	if len(token) == 0 { //参数检测
		w.WriteJson(message.GetErrorMsg(message.ParameterInvalid))
		return
	}

	parm := make(map[string]string)
	parm["refresh_token"] = token

	b, _ := json.Marshal(parm)
	r_body := myhttp.OnPostJson(config.GetRefreshTokenUrl(), string(b))
	if len(r_body) == 0 {
		w.WriteJson(message.GetErrorMsg(message.UnknownError))
		//return
	} else {
		var msg view.MapMessageBody
		json.Unmarshal([]byte(r_body), &msg)
		if msg.State {
			//成功
			var tmp view.UserCacheBody
			tmp.Access_token = msg.Data["access_token"]
			tmp.User_name = msg.Data["username"]
			tmp.Expire_time, _ = strconv.Atoi(msg.Data["expire_time"])

			//保存缓存
			cache := mycache.OnGetCache("oauth2")
			cache.Add(tmp.Access_token, &tmp, time.Duration(tmp.Expire_time)*time.Second)
			//------------------end

			//返回结果
			w.WriteJson(msg)
		} else {
			w.WriteJson(message.GetErrorMsg(msg.Code))
		}
	}
}

/*
	登录
*/
func (a *Login) OnLoginEx(w rest.ResponseWriter, r *rest.Request) {
	//TODO 学生的话（已删除）不能登录
	var req map[string]string
	tools.GetRequestJsonObj(r, &req)

	username := req["username"]
	password := req["password"]
	times := req["time"]

	//判断是否手机号登录
	if len(username) <= 11 {
		if tools.IsPhone(username) {
			tmp := user.OnGetUserNameFromPhone(username)
			if len(tmp) > 0 { //手机号登录直接替换
				username = tmp
			}
		}
	}
	//-------------------------end

	if len(username) == 0 || len(password) == 0 || len(times) == 0 {
		w.WriteJson(message.GetErrorMsg(message.ParameterInvalid))
		return
	}
	mp := make(map[string]interface{})

	tmp := GetAccessTokenByUser(username, password, times)
	if tmp.State {
		//判断用户是否第一次登录，是否绑定手机号
		phone := user.OnGetPhoneFromUserName(username)
		if len(phone) > 0 { //手机号已经绑定
			mp["is_bind_phone"] = true
		} else {
			mp["is_bind_phone"] = false
		}
		//---------------------------------end

		//mp["user"], _ = user.GetUserDetail(username)
		mp["token"] = tmp.Data
		msg := message.GetSuccessMsg(message.NormalMessageId)
		msg.Data = mp
		w.WriteJson(msg)

		//---------------------log
		var logs oplog.Op_log_tbl
		logs.Operator = username
		logs.Topic = "帐号系统"
		logs.Bundle = "登录"
		logs.Pid = "手机登录"
		logs.Ip_addr = tools.GetClientIp(r.Request)
		//logs.Attach0 = info.Phone
		oplog.OpLogBaseAdd(logs) //保存日志
		//---------------end

	} else {
		w.WriteJson(tmp)
	}
	return
}

/*
	修改用户密码
*/
func ChangePwd(w rest.ResponseWriter, r *rest.Request) {
	var req Req_changepwd
	tools.GetRequestJsonObj(r, &req)

	//参数检测
	if !tools.CheckParam(req.Access_token, req.UserName, req.Password) {
		w.WriteJson(message.GetErrorMsg(message.ParameterInvalid, req))
		return
	}

	//验证token，并获取用户名
	username, _, bfind := user.GetUserFromToken(req.Access_token)
	if !bfind {
		w.WriteJson(message.GetErrorMsg(message.TokenFailure))
		return
	}

	//用户名校验错误
	if username != req.UserName {
		w.WriteJson(message.GetErrorMsg(message.NotifyIsNotMatch))
	}

	var db mysqldb.MySqlDB
	defer db.OnDestoryDB()
	orm := db.OnGetDBOrm(config.GetDbUrl())

	var u user.User_tbl
	orm.Where("user = ?", req.UserName).Find(&u)
	if u.Id == 0 {
		w.WriteJson(message.GetErrorMsg(message.NotFindError))
		return
	}
	//判断是否手机号登录
	if len(req.UserName) <= 11 {
		if tools.IsPhone(req.UserName) {
			tmp := user.OnGetUserNameFromPhone(req.UserName)
			if len(tmp) > 0 { //手机号登录直接替换
				req.UserName = tmp
			}
		}
	}

	//oauth2修改密码
	if oauth2.OnChangePwd(req.UserName, req.Password) {
		w.WriteJson(message.GetSuccessMsg())
	} else {
		w.WriteJson(message.GetErrorMsg(message.UserNameDoNotExist))
	}
	return
}

/*
	修改用户密码
*/
func ChangePwdEx(w rest.ResponseWriter, r *rest.Request) {
	var req Req_changepwd
	tools.GetRequestJsonObj(r, &req)

	//参数检测
	if !tools.CheckParam(req.UserName, req.Password) {
		w.WriteJson(message.GetErrorMsg(message.ParameterInvalid, req))
		return
	}

	//验证token，并获取用户名
	_, bfind := user.GetUserDetail(req.UserName)
	if !bfind {
		w.WriteJson(message.GetErrorMsg(message.NotFindError))
		return
	}

	//oauth2修改密码
	if oauth2.OnChangePwd(req.UserName, req.Password) {
		w.WriteJson(message.GetSuccessMsg())
	} else {
		w.WriteJson(message.GetErrorMsg(message.UserNameDoNotExist))
	}
	return
}
